/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    archtimer_test.c
 *  @brief   RISCV Machine Timer testcase source file
 *  @version v1.0
 *  @date    03. Apr. 2023
 ****************************************************************/

#include "printf.h"
#include "mem_map_table.h"
#include "syscounter.h"
#include "crg.h"
#include "irq.h"
#include "hal_api.h"

#define TCIP_BASE_ADDR           MEM_MAP_TCIP_BASE_ADDR

#define MTIMECMPLO_REG_ADDR      (TCIP_BASE_ADDR + 0x4000)
#define MTIMECMPHI_REG_ADDR      (TCIP_BASE_ADDR + 0x4004)

#define MTIMELO_REG_ADDR         (TCIP_BASE_ADDR + 0xBFF8)
#define MTIMEHI_REG_ADDR         (TCIP_BASE_ADDR + 0xBFFC)

#define MTIMER_TIMEOUT_S         2

static void mtimer_irq_handler(void *arg)
{
	arg = arg;
	printf("[MTIMER]: mtimer_irq_handler!\r\n");
	writel(0xFFFFFFFF, MTIMECMPHI_REG_ADDR);
	writel(0xFFFFFFFF, MTIMECMPLO_REG_ADDR);
	Hal_Irq_Disable(Machine_Timer_IRQn);
}

int32_t test_mtimer(void)
{
	uint64_t count = 0;
	uint64_t clk = get_mod_clk_rate(CRG_MOD_SYSCNT);

	printf("\r\n[MTIMER]: TEST START\r\n");

	Hal_Irq_Register(Machine_Timer_IRQn, mtimer_irq_handler, NULL);

	count = readl(MTIMEHI_REG_ADDR);
	count <<= 32;
	count |= readl(MTIMELO_REG_ADDR);

	count += (MTIMER_TIMEOUT_S * clk);

	writel((uint32_t)(count >> 32), MTIMECMPHI_REG_ADDR);
	writel((uint32_t)count, MTIMECMPLO_REG_ADDR);

	Hal_Cnt_DelayMs((MTIMER_TIMEOUT_S + 1) * 1000);
	printf("[MTIMER]: TEST END\r\n");

	return 0;
}

